package com.giraffe.common.redis.service;

import com.giraffe.common.core.utils.DateUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;
import org.springframework.stereotype.Component;

import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.Date;

/**
 * @Author ldx
 * @Date 2023/02/06 16:54
 **/
@Component
public class GenerateCodeService {

  private final static String KEY_FORMAT = "code:index:";

  public static String YYYY = "yyyy";

  public static String YYYYMM = "yyyyMM";

  public static String YYYYMMDD = "yyyyMMdd";

  public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

  private Integer DEFAULT_LENGTH = 8;

  @Autowired(required = false)
  RedisService redisService;

  /**
   *
   * @param ruleCode 编码
   * @return
   */
  public String generateCode(String ruleCode) {
    return generateCode(ruleCode,DEFAULT_LENGTH);
  }

  /**
   *
   * @param ruleCode 编码
   * @return
   */
  public String generateCode(String ruleCode,Integer length) {
    String key = StringUtils.join(KEY_FORMAT,ruleCode);
    RedisAtomicLong counter = new RedisAtomicLong(key, redisService.redisTemplate.getConnectionFactory());
    String currentKey = formatString(counter.incrementAndGet(),length);
    return StringUtils.join(ruleCode,currentKey);
  }

  public String generateCode(String ruleCode,String pattern,Integer length) {
    pattern = StringUtils.isEmpty(pattern) ? YYYYMMDD : pattern;
    length = ObjectUtils.isEmpty(length) ? DEFAULT_LENGTH : length;
    String date = DateUtils.parseDateToStr(pattern, new Date());
    String key = StringUtils.join(KEY_FORMAT,ruleCode);
    RedisAtomicLong counter = new RedisAtomicLong(key, redisService.redisTemplate.getConnectionFactory());
    String currentKey = formatString(counter.incrementAndGet(),length);
    return StringUtils.join(ruleCode,date,currentKey);
  }

  public String generateCode(String ruleCode,int increment) {
    String key = StringUtils.join(KEY_FORMAT,ruleCode);
    RedisAtomicLong counter = new RedisAtomicLong(key, redisService.redisTemplate.getConnectionFactory());
    counter.addAndGet(increment);
    String currentKey = formatString(counter.incrementAndGet(),DEFAULT_LENGTH);
    return StringUtils.join(ruleCode,currentKey);
  }

  private String formatString(long currentKey,Integer length){
    if (currentKey < length) {
      char[] fillChars = new char[length];
      Arrays.fill(fillChars, 0, length, '0');
      DecimalFormat format = new DecimalFormat(new String(fillChars));
      return format.format(currentKey);
    }else{
      return String.valueOf(currentKey);
    }
  }
}
